const fs = require('fs-extra');
const prettier = require('prettier');

import { transformPagesJson } from '@core';

import { resolveFilePath } from '@core/util';

import {
  PROFILE_KEYS,
  PROFILE_DIR,
  decamelize,
  logInfo,
  logSuccess,
  hasOwn,
  PAGE_CONFIG,
  isPlainObject,
  HOME_PAGE,
} from '@shared';
import { option } from 'commander';

import { readRouters, canUseShare } from './util';

function hasLoginAccess(pageAccess) {
  let include = pageAccess.include || [];
  if (typeof include === 'string') {
    include = [include];
  }
  return ~include.indexOf('login');
}

// read
function readPagesJson() {
  const pagesJsonPath = resolveFilePath('pages.json');
  const pagesJsonString = fs.readFileSync(pagesJsonPath, 'utf8');
  return transformPagesJson(pagesJsonString);
}
// init
export function init() {
  const pagesJson = readPagesJson();
  if (!pagesJson) {
    return;
  }
  // routers
  pagesJson.routers.forEach((router) => {
    const filePath = resolveFilePath(router.path) + '.json';
    fs.outputJsonSync(filePath, router, {
      spaces: 2,
    });
    logInfo(`create [${filePath}]`);
  });
  // 开发期间单独配置的几个文件
  PROFILE_KEYS.forEach((key) => {
    const opt = pagesJson[key] ? pagesJson[key] : {};
    const filePath = resolveFilePath(PROFILE_DIR, decamelize(key) + '.json');
    fs.outputJsonSync(filePath, opt, {
      spaces: 2,
    });
    logInfo(`create [${filePath}]`);
  });
  // 其他
  const extrasFilePath = resolveFilePath(PROFILE_DIR, 'extras.json');
  fs.outputJsonSync(extrasFilePath, pagesJson.extras, {
    spaces: 2,
  });
  logInfo(`create [${extrasFilePath}]`);

  logSuccess('vni init success...');

  return pagesJson;
}
// clear
export function clear() {
  const pagesJson = readPagesJson();
  if (!pagesJson) {
    return;
  }
  // routers
  pagesJson.routers.forEach((router) => {
    const filePath = resolveFilePath(router.path) + '.json';
    fs.removeSync(filePath);
  });
  // options
  fs.removeSync(resolveFilePath(PROFILE_DIR));

  return;
}

function serializePath(path, query) {
  if (query) {
    if (~path.indexOf('?')) {
      path += '&';
    } else {
      path += '?';
    }
    for (var key in query) {
      path += `${key}=${query[key]}&`;
    }
    return path.replace(/\&$/, '');
  } else {
    return path;
  }
}

// TODO 这里应当从配置文件读取
const shareFieldKeyMap = {
  PATH: '_s_path',
  QUERY: '_s_query',
  UID: '_s_uid',
};

// 导出页面路径规则
export function outputPagePathRules(options) {
  // TODO 暂时在这里处理，后面在拆分模块。
  const routers = readRouters();
  const homePage = routers.find((router) => {
    return router && router[HOME_PAGE];
  });
  const INDEX_PATH = homePage.path;
  const rules = [];
  routers.forEach(function (router) {
    const pagePath = router.path;
    const pageConfig = hasOwn(router, PAGE_CONFIG) ? router[PAGE_CONFIG] : {};
    const canInvoke = canUseShare(pagePath) || hasOwn(pageConfig, 'link');
    if (canInvoke) {
      const pageAccess = pageConfig.access || {};
      if (pageConfig.using !== false) {
        // 检测下是否能直达，未登录可访问以及主动设置 direct 属性
        let pageLink = pageConfig.link || {};
        let pageQuery = pageLink.query;

        // 处理下占位
        if (pageQuery) {
          for (let key in pageQuery) {
            if (
              isPlainObject(pageQuery[key]) &&
              hasOwn(pageQuery[key], '#name')
            ) {
              pageQuery[key] = `[${pageQuery[key]['#name']}]`;
            }
          }
        }

        let isDirect = hasLoginAccess(pageAccess) || pageLink.mode === 'direct';
        let shareUrl = '';
        let innerLink = '';
        innerLink = serializePath(pagePath, pageQuery);
        if (isDirect) {
          shareUrl = innerLink;
        } else {
          if (pageLink.mode === 'action') {
            shareUrl = serializePath(`${INDEX_PATH}?_source=share`, pageQuery);
          } else {
            shareUrl =
              INDEX_PATH +
              `?_source=share&${shareFieldKeyMap.PATH}=/${pagePath}`;
            if (pageQuery) {
              shareUrl += `&${shareFieldKeyMap.QUERY}=${JSON.stringify(
                pageQuery
              )}`;
            }
          }
        }
        const pageName = pageConfig.name || '页面名称未知';

        rules.push({
          pagePath,
          shareUrl,
          innerLink,
          name: pageName,
          description: pageConfig.description || pageName,
        });
      }
    }
  });

  var linkPath = '';
  if (options.output && options.output.link) {
    linkPath = options.output.link.filename;
    if (options.app) {
      linkPath += `${options.app}_links.js`;
    } else {
      linkPath += `links.js`;
    }
  }
  if (!linkPath) {
    linkPath = 'src/link.js';
  }

  const varName = options.app ? `${options.app}_links` : 'links';
  let linksBundle =
    `var ${varName} = ` +
    JSON.stringify(rules, {
      spaces: 2,
    });

  linksBundle = prettier.format(linksBundle, {
    tabWidth: 2,
    singleQuote: true,
    parser: 'babel',
  });

  fs.outputFileSync(linkPath, linksBundle);
}
